#

| Chapter 23 Removing Files |

## 23.21 Removing Every File but One

One problem with UNIX: it's not terribly good at "excluding" things. There's no option to rm that says, "Do what you will with everything else, but please don't delete these files." You can sometimes create a complex wildcard expression (1.16) that does what you want - but sometimes that's a lot of work, or maybe even impossible.

Here's one place where UNIX's command substitution (9.16) operators (backquotes) come to the rescue. You can use use ls to list all the files, pipe the output into a grep -v or egrep -v (27.3) command, and then use backquotes to give the resulting list to rm. Here's what this command would look like:

>     % rm -i `ls -d *.txt | grep -v '^john\.txt$'`

[Actually, when you're matching just one filename, fgrep -v -x (27.6) might be better. -JP ] This command deletes all files whose names end in .txt, except for john.txt. I've probably been more careful than you need to be about making sure there aren't any extraneous matches; in most cases, grep -v john would probably suffice. Using ls -d (16.8) makes sure that ls doesn't look into any subdirectories and give you those filenames. The rm -i (21.11) asks you before removing each file; if you're sure of yourself, omit the -i.

Of course, if you want to exclude two files, you can do that with egrep:

>     % rm `ls -d *.txt | egrep -v 'john|mary'`

(Not all egrep implementations support the -v option. Don't forget to quote the vertical bar (`|`), to prevent the shell from piping egrep's output to mary.)

Another solution is the nom (15.9) script.

- ML

23.20 Deleting Stale Files |  | 23.22 Using find to Clear Out Unneeded Files